iT邦幫忙

2025 iThome 鐵人賽

DAY 2
1
自我挑戰組

用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting系列 第 2

Day 2 | 用 wchar_t* 畫畫?Console 也能做遊戲畫面!Part 1

  • 分享至 

  • xImage
  •  

這裡是鐵匠史密斯,最初被C++大神 javidx9 的影片吸引的地方就是:
使用Console主控台呈現遊戲畫面!

Console 呈現畫面?

不是使用OpenGL,也不是使用Unity, Unreal Engine?
那我們就用Console來渲染屬於自己的遊戲!
原始、簡單、粗暴,最適合我了

一切的開始 : Console畫面緩衝區

我們要用Console來呈現遊戲畫面,就要建立一個屬於自己的自定義畫面緩衝區;
Microsoft對畫面緩衝區的介紹

「畫面緩衝區」是在主控台視窗輸出中字元和色彩資料的陣列
「作用中的畫面緩衝區」是顯示在畫面上的緩衝區。

所以,我們要做的兩個流程是 :

  • 第一步: 製作屬於自己的畫面緩衝區
  • 第二步: 顯示在主控台上,成為作用中的畫面緩衝區

不過第二步,我會放到明天的 Day 3 :P
今天,我們先專注在第一步 —— 製作屬於自己的畫面緩衝區(畫布)!
以下的程式碼均在main.cpp裡的main()呈現~ 直接把程式碼都塞在main()裡面吧

製作畫面緩衝區screen(一維陣列)

直接製作一個資料型態為wchar_t*的一維陣列吧:

    const int nScreenWidth { 80 };
    const int nScreenHeight { 30 };
    
    // Create the canvas
    wchar_t* screen{ new wchar_t[nScreenWidth * nScreenHeight] };

這裡的screen是我們的主角,自定義的畫面緩衝區(寬80 , 高30),也是一塊一維陣列(其實是個wchar_t*指標),可儲存80 * 30 = 2400 個字元

它的用途是:
暫存整個畫面上所有要顯示的字元(像主控台內的各個像素)。

為什麼使用wchar_t,而不是char?
wchar_t(wide character, 擴充字元):儲存char(character, 字元)無法儲存的Unicode字元(ex: 中文、日文、圖形等等),可以想像成Unicode編碼格式的字元太大了,沒辦法塞入只能存1 byte的char

寫入畫面緩衝區內容

直接用for迴圈,把一維陣列的每個元素(字元)填滿吧,先填一些空白(' '),然後再填入 % 字元:

for (int i = 0; i < nScreenWidth * nScreenHeight; i++)
{
    if (i < 1000)
        screen[i] = L' ';
    else
        screen[i] = L'%';
}
screen[nScreenWidth * nScreenHeight - 1] = '\0';

補充說明:

  • L' ' 是寬字元的空格(對應 wchar_t
  • screen[i] 就是我們操作每一格畫素
  • 整個畫面是 2400 格,其中前 1000 是空白,後 1400 是 %,像是畫面被切一半!

如果你對指標有一點熟,也許你會注意到:

  • screen 是一個 wchar_t*,其實就是指標,他指向一個記憶體區塊(陣列 array)的第一個元素(紀錄陣列第一個元素的記憶體位置)
  • screen[i] 就能操作每一格的值(因為陣列特定元素的值 = 指標 + offset)

為什麼要加 \0 ?

\0為C/C++ 中「字串結尾符號」(null terminator)。

很多函式(包括 Windows 輸出函式)在處理字串時會靠 \0 判斷「何時停止輸出」,避免使用Console印出字元時造成印出陣列範圍外的無用數值(garbage data)
所以判斷「何時停止輸出」非常重要!

今日總結 :

  • 怎麼用一維陣列模擬畫面像素
  • 如何用 wchar_t* 建立畫面緩衝區(畫布)
  • 為什麼 wchar_tchar 更適合畫 Console 畫面
  • \0 的用途與重要性
  • 順便複習了一點指標與陣列的關係

下一篇(Day 3),我會把畫面內容「真正貼上 Console」,並嘗試理解 Windows.h 中的一些函式是怎麼讓我們的畫布顯示出來的(雖然我現在對這些還是很懵,也請各位大佬指點了~)
第一次寫文章,排版有待加強,日後會回來持續調整內容/排版(鐵人賽不簡單阿...)

我們繼續走下去~


上一篇
Day 1 | 前言: 我為什麼決定用 C++ 做一個 第一人稱視角 遊戲?
下一篇
Day 3 | 用 wchar_t* 畫畫?Console 也能做遊戲畫面!Part 2
系列文
用 C++ 實作簡易第一人稱視角遊戲:從入門到理解 Ray Casting30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言